﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using IdentityService.Domain.Core.Ioc;
using Microsoft.Extensions.DependencyModel;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollectionExtension
    {
        /// <summary>
        /// Services that automatically register the current assembly and other referenced assemblies
        /// </summary>
        /// <param name="services"></param>
        public static void AddAutoDependencyInjection(this IServiceCollection services)
        {
            var deps = DependencyContext.Default;

            var libs = deps!.CompileLibraries
                .Where(lib =>
                lib != null &&
                !lib.Serviceable &&
                lib.Type != "package");

            var allAssemblies = new List<Assembly>();
            foreach (var lib in libs)
            {
                var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
                allAssemblies.Add(assembly);
            }

            foreach (var serviceAsm in allAssemblies)
            {
                var serviceList = serviceAsm.GetTypes().Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface);
                foreach (Type serviceType in serviceList.Where(t => typeof(IScopedDependency).IsAssignableFrom(t)))
                {
                    var interfaceTypes = serviceType.GetInterfaces();

                    if (interfaceTypes.Count() == 1)
                    {
                        services.AddScoped(serviceType, serviceType);
                    }
                    foreach (var interfaceType in interfaceTypes)
                    {
                        services.AddScoped(interfaceType, serviceType);
                    }
                }

                foreach (Type serviceType in serviceList.Where(t => typeof(ISingletonDependency).IsAssignableFrom(t)))
                {
                    var interfaceTypes = serviceType.GetInterfaces();
                    if (interfaceTypes.Count() == 1)
                    {
                        services.AddSingleton(serviceType, serviceType);
                    }

                    foreach (var interfaceType in interfaceTypes)
                    {
                        services.AddSingleton(interfaceType, serviceType);
                    }
                }

                foreach (Type serviceType in serviceList.Where(t => typeof(ITransientDependency).IsAssignableFrom(t)))
                {
                    var interfaceTypes = serviceType.GetInterfaces();
                    if (interfaceTypes.Count() == 1)
                    {
                        services.AddTransient(serviceType, serviceType);
                    }
                    foreach (var interfaceType in interfaceTypes)
                    {
                        services.AddTransient(interfaceType, serviceType);
                    }
                }
            }




        }


        private static void RegisterToIoc(Type t, Func<IServiceCollection, Type, Type> func)
        {



        }






    }
}